﻿using Share;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public static class GameObjectExtensions
{
    //加速节点下所有粒子的播放速度
    public static void SetAllSpeed(this GameObject gb, float order)
    {

    }
    public static void SetSortOrder(this GameObject gb, int order)
    {
        if (gb == null)
            return;

        // 处理Canvas组件
        var canvas = gb.GetComponent<Canvas>();
        if (canvas != null)
        {
            canvas.sortingOrder = order;
        }

        // 处理Renderer组件
        var renderer = gb.GetComponent<Renderer>();
        if (renderer != null)
        {
            renderer.sortingOrder = order;
        }

        // 处理粒子系统
        var particleSystem = gb.GetComponent<ParticleSystem>();
        if (particleSystem != null)
        {
            var particleRenderer = particleSystem.GetComponent<Renderer>();
            if (particleRenderer != null)
            {
                particleRenderer.sortingOrder = order;
            }
        }


        // 递归处理所有子节点
        foreach (Transform child in gb.transform)
        {
            child.gameObject.SetSortOrder(order);
        }
    }

    /// <summary>
    /// 查找或创建指定名称的子节点并返回其Transform。
    /// </summary>
    /// <param name="gb">父GameObject。</param>
    /// <param name="strNode">子节点名称。</param>
    /// <returns>找到或创建的子节点的Transform。</returns>
    public static Transform GetOrAddNode(this GameObject gb, string strNode)
    {
        var obj = gb.FindDeepChildByName(strNode);
        if (obj != null)
            return obj.transform;
        obj = new GameObject(strNode);
        obj.transform.parent = gb.transform;
        obj.transform.localPosition = Vector3.zero;
        return obj.transform;
    }

    /// <summary>
    /// 递归获取所有子对象的激活状态并记录日志。
    /// </summary>
    /// <param name="gb">父GameObject。</param>
    public static void GetActiveChildListDesc(this GameObject gb)
    {
        string str = "";
        var nodes = gb.transform.GetComponentsInChildren<Transform>(true);
        foreach (var node in nodes)
        {
            str += node.name + "   =" + node.gameObject.activeInHierarchy.ToString() + "\n";
            if (str.Length > 1000) // 限制日志长度
                break;
        }
        Share.XKLog.LogError(str);
    }

    /// <summary>
    /// 获取或添加指定类型的组件。
    /// </summary>
    /// <typeparam name="T">组件类型。</typeparam>
    /// <param name="gb">GameObject。</param>
    /// <returns>找到或添加的组件。</returns>
    public static T GetOrAddComponent<T>(this GameObject gb) where T : UnityEngine.Component
    {
        if (gb == null)
            return null;
        if (!typeof(T).IsSubclassOf(typeof(UnityEngine.Component)))
            throw new ArgumentException("Type parameter must be a subclass of UnityEngine.Component");
        var com = gb.GetComponent<T>();
        if (com == null)
            com = gb.AddComponent<T>();
        return com;
    }

    /// <summary>
    /// 获取GameObject的完整路径名称。
    /// </summary>
    /// <param name="obj">GameObject。</param>
    /// <returns>GameObject的完整路径名称。</returns>
    public static string GetFullName(this GameObject obj)
    {
        string str = obj.name;
        Transform parent = obj.transform.parent;
        while (parent != null)
        {
            str = parent.name + "->" + str;
            parent = parent.parent;
        }
        return str;
    }



    /// <summary>
    /// 将对象设置为指定父对象的子对象，并重置其局部变换。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="parent">父Transform。</param>
    public static void SetObjectZeroParent(this GameObject gb, Transform parent)
    {
        gb.transform.parent = parent;
        gb.transform.localPosition = Vector3.zero;
        gb.transform.localEulerAngles = Vector3.zero;
        gb.transform.localRotation = Quaternion.identity;
        //gb.transform.localScale = Vector3.one;
    }

    /// <summary>
    /// 递归更改对象及其子对象中所有Image和Text的颜色。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="color">颜色。</param>
    public static void MakeColor(this GameObject gb, Color color)
    {
        var images = gb.GetComponentsInChildren<Image>();
        foreach (var image in images)
        {
            image.color = color;
        }
        var texts = gb.GetComponentsInChildren<Text>();
        foreach (var text in texts)
        {
            text.color = color;
        }
    }

    /// <summary>
    /// 递归更改对象及其子对象的Layer。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="targetLayer">目标Layer名称。</param>
    public static void ChangeLayer(this GameObject gb, string targetLayer)
    {
        int layer = LayerMask.NameToLayer(targetLayer);
        if (layer == -1)
        {
            XKLog.LogError("Layer中不存在，请手动添加LayerName: " + targetLayer);
            return;
        }
        gb.layer = layer;
        foreach (Transform child in gb.transform)
        {
            child.gameObject.ChangeLayer(targetLayer);
        }
    }

    /// <summary>
    /// 递归设置对象及其子对象的Layer，如果当前Layer与自定义Layer匹配。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="layer">目标Layer。</param>
    /// <param name="strCustomLayer">自定义Layer名称。</param>
    /// <returns>是否修改了Layer。</returns>
    public static bool SetAllChildLayer(this GameObject gb, int layer, string strCustomLayer = "")
    {
        if (gb == null)
            return false;
        bool modify = false;
        if (!string.IsNullOrEmpty(strCustomLayer))
        {
            if (gb.layer == LayerMask.NameToLayer(strCustomLayer))
            {
                gb.layer = layer;
                modify = true;
            }
        }
        else
        {
            gb.layer = layer;
            modify = true;
        }
        foreach (Transform child in gb.transform)
        {
            if (child.gameObject.SetAllChildLayer(layer, strCustomLayer))
                modify = true;
        }
        return modify;
    }

    /// <summary>
    /// 递归设置对象及其子对象的Layer，如果当前Layer与自定义Layer不匹配。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="layer">目标Layer。</param>
    /// <param name="strCustomLayer">自定义Layer名称。</param>
    /// <returns>是否修改了Layer。</returns>
    public static bool SetAllChildLayerExclude(this GameObject gb, int layer, string strCustomLayer = "")
    {
        if (gb == null)
            return false;
        bool modify = false;
        if (string.IsNullOrEmpty(strCustomLayer) || gb.layer != LayerMask.NameToLayer(strCustomLayer))
        {
            gb.layer = layer;
            modify = true;
        }
        foreach (Transform child in gb.transform)
        {
            if (child.gameObject.SetAllChildLayerExclude(layer, strCustomLayer))
                modify = true;
        }
        return modify;
    }

    /// <summary>
    /// 递归设置对象及其子对象的Layer，通过Layer名称。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="strName">目标Layer名称。</param>
    /// <param name="strCustomLayer">自定义Layer名称。</param>
    /// <returns>是否修改了Layer。</returns>
    public static bool SetAllChildLayer(this GameObject gb, string strName, string strCustomLayer = "")
    {
        int layer = LayerMask.NameToLayer(strName);
        return SetAllChildLayer(gb, layer, strCustomLayer);
    }

    /// <summary>
    /// 递归设置对象及其子对象的Layer，通过Layer名称，如果当前Layer与自定义Layer不匹配。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="strName">目标Layer名称。</param>
    /// <param name="strCustomLayer">自定义Layer名称。</param>
    /// <returns>是否修改了Layer。</returns>
    public static bool SetAllChildLayerExclude(this GameObject gb, string strName, string strCustomLayer = "")
    {
        int layer = LayerMask.NameToLayer(strName);
        return SetAllChildLayerExclude(gb, layer, strCustomLayer);
    }
    /// <summary>
    /// 递归设置对象及其子对象的Tag。
    /// </summary>
    /// <param name="gb">GameObject。</param>
    /// <param name="strName">Tag名称。</param>
    public static void SetAllChildTag(this GameObject gb, string strName)
    {
        if (gb != null)
        {
            gb.tag = strName;
        }
        foreach (Transform child in gb.transform)
        {
            child.gameObject.SetAllChildTag(strName);
        }
    }

    public static void Destroy(this GameObject gb)
    {
        if (gb)
            GameObject.Destroy(gb);
    }
    /// <summary>
    /// 销毁 GameObject（编辑器模式下立即销毁）。
    /// </summary>
    /// <param name="gb">要销毁的 GameObject。</param>
    public static void StopOrDestroy(this GameObject gb)
    {
        if (gb == null)
            return;
        float fDelay = -1;
        bool bDelay = false;
        var pads = gb.GetComponentsInChildren<PsActionDestruct>(true);
        bool bHaveDestruct = false;
        foreach (var pad in pads)
        {
            if (pad.delayTime > 0)
            {
                bDelay = true;
                //bDelay = true;
                if (pad.gameObject != gb)
                {
                    // 找到节点下，所有延迟删除的点，取最大的值设定给自己
                    if (fDelay < pad.delayTime)
                        fDelay = pad.delayTime;
                    if (!pad.enabled)
                    {
                        pad.enabled = true;
                    }
                }
                else
                {
                    bHaveDestruct = true;
                    if (!pad.enabled)
                    {
                        pad.enabled = true;
                    }
                }
            }
            //if(!pad.enabled)
            //    pad.enabled = true;
        }
        if (fDelay > 0 && !bHaveDestruct)
        {
            var p = gb.GetOrAddComponent<PsActionDestruct>();
            if (p)
            {
                p.DoSetDelayTime(fDelay);
            }
            bDelay = true;
        }
        if (!bDelay)
        {
#if UNITY_EDITOR
            GameObject.Destroy(gb);
#else
                    GameObject.Destroy(gb);
#endif
        }

    }

    /// <summary>
    /// 清除所有子对象。
    /// </summary>
    /// <param name="gb">目标 GameObject。</param>
    public static void ClearChild(this GameObject gb)
    {
        // 检查传入的 GameObject 是否为空
        if (gb == null)
        {
            XKLog.LogWarning("尝试清除子对象时，传入的 GameObject 为 null，已跳过操作。");
            return;
        }

        // 获取子对象数量
        int childCount = gb.transform.childCount;

        // 如果没有子对象，直接返回
        if (childCount == 0)
        {
            return;
        }

        // 缓存子对象列表以减少重复访问
        Transform[] children = new Transform[childCount];
        for (int i = 0; i < childCount; i++)
        {
            children[i] = gb.transform.GetChild(i);
        }

        // 根据运行时环境选择销毁方式
        for (int i = children.Length - 1; i >= 0; i--)
        {
            if (Application.isPlaying)
            {
                GameObject.Destroy(children[i].gameObject); // 运行时使用 Destroy
            }
            else
            {
                GameObject.DestroyImmediate(children[i].gameObject); // 编辑器模式下使用 DestroyImmediate
            }
        }
    }

    /// <summary>
    /// 深度查找指定名称的子对象。
    /// </summary>
    /// <param name="gb">父GameObject。</param>
    /// <param name="strName">子对象名称。</param>
    /// <returns>找到的子对象。</returns>
    public static GameObject FindDeepChildByName(this GameObject gb, string strName)
    {
        // 参数校验
        if (gb == null || string.IsNullOrEmpty(strName))
        {
            XKLog.LogError($"查找节点失败: 子对象名称为 {strName}, 父对象为 {(gb != null ? gb.name : "null")}");
            return null;
        }

        Transform rootTransform = gb.transform;
        if (rootTransform == null)
        {
            XKLog.LogError($"查找节点失败: 父对象的 Transform 为 null, 子对象名称为 {strName}, 父对象名称为 {gb.name}");
            return null;
        }

        // 使用队列实现广度优先搜索
        Queue<Transform> queue = new Queue<Transform>();
        queue.Enqueue(rootTransform);

        while (queue.Count > 0)
        {
            var current = queue.Dequeue();
            if (current != null && current.name == strName)
            {
                return current.gameObject;
            }

            foreach (Transform child in current)
            {
                if (child != null) // 防止空引用
                {
                    queue.Enqueue(child);
                }
            }
        }

        // 查找失败时记录更详细的日志
        XKLog.LogWarning($"未找到子对象: 子对象名称为 {strName}, 父对象名称为 {gb.name}");
        return null;
    }
    public static void SetPositionFromUINode(this GameObject gb, Vector3 pos)
    {
        Vector3 worldPos = RectTransformUtility.WorldToScreenPoint(Camera.main, pos);
        worldPos.z = 100;
        gb.transform.position = worldPos;
        worldPos = gb.transform.localPosition;
        worldPos.z = 100;
        gb.transform.localPosition = worldPos;
        gb.transform.localScale = Vector3.one;
    }

    public static void SetDir(this GameObject gb, float dir = 0)
    {
        var scale = gb.transform.localScale;
        if (dir != 0)
        {
            scale.x *= dir;
        }
        gb.transform.localScale = scale;
    }

}
